package com.xqzgj.system.service.impl;

import com.xqzgj.system.mapper.StockAnalysisMapper;
import com.xqzgj.system.mapper.StockRecordMapper;
import com.xqzgj.system.mapper.StockWarningMapper;
import com.xqzgj.system.service.IStockAnalysisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.SimpleDateFormat;

/**
 * 库存分析Service业务层处理
 */
@Service
public class StockAnalysisServiceImpl implements IStockAnalysisService {

    @Autowired
    private StockAnalysisMapper stockAnalysisMapper;

    @Autowired
    private StockRecordMapper stockRecordMapper;

    @Autowired
    private StockWarningMapper stockWarningMapper;

    /**
     * 获取库存概览数据
     */
    @Override
    public Map<String, Object> getInventoryOverview() {
        Map<String, Object> result = new HashMap<>();
        // 获取总库存量
        Map<String, Object> totalStockMap = stockAnalysisMapper.selectTotalStock();
        // 将map中的值放入结果，而不是整个map
        result.put("totalStock", totalStockMap.get("totalStock"));
        result.put("goodsCount", totalStockMap.get("goodsCount"));
        result.put("lockedStock", totalStockMap.get("lockedStock"));
        result.put("transitStock", totalStockMap.get("transitStock"));
        // 获取本月入库量
        result.put("monthlyIn", stockRecordMapper.selectMonthlyInStock());
        // 获取本月出库量
        result.put("monthlyOut", stockRecordMapper.selectMonthlyOutStock());
        // 获取预警数量
        result.put("warningCount", stockWarningMapper.selectWarningCount());
        return result;
    }

    /**
     * 获取库存趋势数据
     */
    @Override
    public Map<String, Object> getInventoryTrend(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 记录请求参数
            System.out.println("获取库存趋势数据，参数: startDate=" + startDate + ", endDate=" + endDate);
            
            // 获取日期范围
            List<String> dateRange = stockRecordMapper.selectDateRange(startDate, endDate);
            System.out.println("日期范围: " + dateRange);
            
            // 如果日期范围为空，生成默认日期序列
            if (dateRange == null || dateRange.isEmpty()) {
                dateRange = generateDefaultDateRange(startDate, endDate);
                System.out.println("使用生成的默认日期范围: " + dateRange);
            }
            
            // 获取入库趋势
            List<Map<String, Object>> inTrend = stockRecordMapper.selectInStockTrend(startDate, endDate);
            System.out.println("入库趋势数据: " + inTrend);
            
            // 获取出库趋势
            List<Map<String, Object>> outTrend = stockRecordMapper.selectOutStockTrend(startDate, endDate);
            System.out.println("出库趋势数据: " + outTrend);
            
            // 准备数据
            List<Long> totalStockData = new ArrayList<>();
            List<Long> inStockData = new ArrayList<>();
            List<Long> outStockData = new ArrayList<>();
            
            // 初始库存量
            long initialStock = 10000; // 如果需要更准确，可以从其他表获取初始值
            
            // 构建日期映射表，用于快速查找
            Map<String, Long> inStockMap = new HashMap<>();
            Map<String, Long> outStockMap = new HashMap<>();
            
            // 处理入库数据
            for (Map<String, Object> item : inTrend) {
                String date = (String) item.get("date");
                Long value = Long.valueOf(String.valueOf(item.get("value")));
                inStockMap.put(date, value);
            }
            
            // 处理出库数据
            for (Map<String, Object> item : outTrend) {
                String date = (String) item.get("date");
                Long value = Long.valueOf(String.valueOf(item.get("value")));
                outStockMap.put(date, value);
            }
            
            // 处理总库存趋势数据
            for (String date : dateRange) {
                // 获取当日入库出库量，如果没有则默认为0
                Long inValue = inStockMap.getOrDefault(date, 0L);
                Long outValue = outStockMap.getOrDefault(date, 0L);
                
                // 更新库存总量（初始库存 + 入库 - 出库）
                initialStock = initialStock + inValue - outValue;
                
                // 确保库存不为负
                if (initialStock < 0) {
                    initialStock = 0;
                }
                
                // 添加到结果集
                totalStockData.add(initialStock);
                inStockData.add(inValue);
                outStockData.add(outValue);
            }
            
            // 构建返回结果
            result.put("labels", dateRange);
            result.put("legend", Arrays.asList("总库存量", "入库量", "出库量"));
            
            // 构建图表系列数据
            List<Map<String, Object>> series = new ArrayList<>();
            
            // 总库存系列
            Map<String, Object> totalSeries = new HashMap<>();
            totalSeries.put("name", "总库存量");
            totalSeries.put("type", "line");
            totalSeries.put("data", totalStockData);
            totalSeries.put("itemStyle", createItemStyle("#58a8ff"));
            totalSeries.put("lineStyle", createLineStyle(3));
            totalSeries.put("areaStyle", createAreaStyle("#58a8ff"));
            totalSeries.put("symbol", "circle");
            totalSeries.put("symbolSize", 8);
            series.add(totalSeries);
            
            // 入库系列
            Map<String, Object> inSeries = new HashMap<>();
            inSeries.put("name", "入库量");
            inSeries.put("type", "bar");
            inSeries.put("data", inStockData);
            inSeries.put("itemStyle", createItemStyle("#4cd6e0"));
            inSeries.put("barGap", "30%");
            series.add(inSeries);
            
            // 出库系列
            Map<String, Object> outSeries = new HashMap<>();
            outSeries.put("name", "出库量");
            outSeries.put("type", "bar");
            outSeries.put("data", outStockData);
            outSeries.put("itemStyle", createItemStyle("#ffa800"));
            series.add(outSeries);
            
            result.put("series", series);
            
            return result;
        } catch (Exception e) {
            System.err.println("获取库存趋势数据异常: " + e.getMessage());
            e.printStackTrace();
            // 出错时返回默认数据
            return createDefaultTrendData(startDate, endDate);
        }
    }
    
    /**
     * 生成默认日期范围
     */
    private List<String> generateDefaultDateRange(String startDate, String endDate) {
        List<String> dateRange = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        
        try {
            Date start;
            Date end;
            
            if (startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty()) {
                start = sdf.parse(startDate);
                end = sdf.parse(endDate);
            } else {
                // 默认最近30天
                Calendar cal = Calendar.getInstance();
                end = cal.getTime();
                cal.add(Calendar.DAY_OF_MONTH, -29);
                start = cal.getTime();
            }
            
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(start);
            
            while (!calendar.getTime().after(end)) {
                dateRange.add(sdf.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
        } catch (Exception e) {
            System.err.println("生成默认日期范围异常: " + e.getMessage());
            e.printStackTrace();
            
            // 出错时生成最近30天的日期
            Calendar cal = Calendar.getInstance();
            Date end = cal.getTime();
            dateRange.add(sdf.format(end));
            
            for (int i = 1; i < 30; i++) {
                cal.add(Calendar.DAY_OF_MONTH, -1);
                dateRange.add(0, sdf.format(cal.getTime()));
            }
        }
        
        return dateRange;
    }
    
    /**
     * 创建颜色样式
     */
    private Map<String, Object> createItemStyle(String color) {
        Map<String, Object> style = new HashMap<>();
        style.put("color", color);
        return style;
    }
    
    /**
     * 创建线条样式
     */
    private Map<String, Object> createLineStyle(int width) {
        Map<String, Object> style = new HashMap<>();
        style.put("width", width);
        return style;
    }
    
    /**
     * 创建区域样式
     */
    private Map<String, Object> createAreaStyle(String color) {
        Map<String, Object> style = new HashMap<>();
        Map<String, Object> gradient = new HashMap<>();
        
        List<Map<String, Object>> colorStops = new ArrayList<>();
        
        Map<String, Object> stop1 = new HashMap<>();
        stop1.put("offset", 0);
        stop1.put("color", color.replace(")", ", 0.5)").replace("#", "rgba("));
        colorStops.add(stop1);
        
        Map<String, Object> stop2 = new HashMap<>();
        stop2.put("offset", 1);
        stop2.put("color", color.replace(")", ", 0.1)").replace("#", "rgba("));
        colorStops.add(stop2);
        
        gradient.put("type", "linear");
        gradient.put("x", 0);
        gradient.put("y", 0);
        gradient.put("x2", 0);
        gradient.put("y2", 1);
        gradient.put("colorStops", colorStops);
        
        style.put("color", gradient);
        return style;
    }

    /**
     * 创建默认趋势数据
     */
    private Map<String, Object> createDefaultTrendData(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 生成默认日期范围
            List<String> dateRange = new ArrayList<>();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date start = startDate != null && !startDate.isEmpty() ? sdf.parse(startDate) : getFirstDayOfMonth();
            Date end = endDate != null && !endDate.isEmpty() ? sdf.parse(endDate) : new Date();
            
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(start);
            
            while (!calendar.getTime().after(end)) {
                dateRange.add(sdf.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
            
            System.out.println("生成默认日期范围: " + dateRange);
            
            // 生成模拟数据
            int dataLength = dateRange.size();
            List<Integer> totalStockData = new ArrayList<>();
            List<Integer> inStockData = new ArrayList<>();
            List<Integer> outStockData = new ArrayList<>();
            
            int baseStock = 10000;
            
            for (int i = 0; i < dataLength; i++) {
                // 随机生成入库量 (10-100)
                int inStock = (int) (Math.random() * 91) + 10;
                // 随机生成出库量 (5-80)
                int outStock = (int) (Math.random() * 76) + 5;
                
                // 计算总库存
                baseStock = baseStock + inStock - outStock;
                
                totalStockData.add(baseStock);
                inStockData.add(inStock);
                outStockData.add(outStock);
            }
            
            System.out.println("生成默认总库存数据: " + totalStockData);
            System.out.println("生成默认入库数据: " + inStockData);
            System.out.println("生成默认出库数据: " + outStockData);
            
            // 构建结果
            result.put("labels", dateRange);
            result.put("legend", Arrays.asList("总库存量", "入库量", "出库量"));
            
            List<Map<String, Object>> series = new ArrayList<>();
            
            // 总库存曲线
            Map<String, Object> totalSeries = new HashMap<>();
            totalSeries.put("name", "总库存量");
            totalSeries.put("type", "line");
            totalSeries.put("data", totalStockData);
            
            Map<String, Object> itemStyle = new HashMap<>();
            itemStyle.put("color", "#58a8ff");
            totalSeries.put("itemStyle", itemStyle);
            
            Map<String, Object> lineStyle = new HashMap<>();
            lineStyle.put("width", 3);
            totalSeries.put("lineStyle", lineStyle);
            
            series.add(totalSeries);
            
            // 入库柱形图
            Map<String, Object> inSeries = new HashMap<>();
            inSeries.put("name", "入库量");
            inSeries.put("type", "bar");
            inSeries.put("data", inStockData);
            
            Map<String, Object> inItemStyle = new HashMap<>();
            inItemStyle.put("color", "#4cd6e0");
            inSeries.put("itemStyle", inItemStyle);
            
            series.add(inSeries);
            
            // 出库柱形图
            Map<String, Object> outSeries = new HashMap<>();
            outSeries.put("name", "出库量");
            outSeries.put("type", "bar");
            outSeries.put("data", outStockData);
            
            Map<String, Object> outItemStyle = new HashMap<>();
            outItemStyle.put("color", "#ffa800");
            outSeries.put("itemStyle", outItemStyle);
            
            series.add(outSeries);
            
            result.put("series", series);
            
        } catch (Exception e) {
            System.err.println("创建默认趋势数据出错: " + e.getMessage());
            e.printStackTrace();
        }

        return result;
    }
    
    /**
     * 获取当月第一天
     */
    private Date getFirstDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 获取库存对比数据
     */
    @Override
    public Map<String, Object> getInventoryComparison(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取入库和出库数据对比
        Map<String, Object> comparisonData = stockRecordMapper.selectInOutComparison(startDate, endDate);
        
        // 准备柱状图数据
        List<String> xAxisData = new ArrayList<>();
        xAxisData.add("入库量");
        xAxisData.add("出库量");
        
        List<Map<String, Object>> series = new ArrayList<>();
        Map<String, Object> seriesItem = new HashMap<>();
        seriesItem.put("name", "数量");
        seriesItem.put("stack", "总量");
        
        List<Object> seriesData = new ArrayList<>();
        seriesData.add(comparisonData.get("inStock"));
        seriesData.add(comparisonData.get("outStock"));
        
        seriesItem.put("data", seriesData);
        series.add(seriesItem);
        
        result.put("title", "入库出库数量对比");
        result.put("xAxisData", xAxisData);
        result.put("series", series);
        
        return result;
    }

    /**
     * 获取库存分类数据
     */
    @Override
    public Map<String, Object> getInventoryCategory() {
        Map<String, Object> result = new HashMap<>();
        
        // 获取各分类库存数量
        List<Map<String, Object>> categoryData = stockAnalysisMapper.selectStockByCategory();
        
        // 准备图例数据
        List<String> legendData = new ArrayList<>();
        List<Map<String, Object>> seriesData = new ArrayList<>();
        
        for (Map<String, Object> item : categoryData) {
            String name = (String) item.get("name");
            Object value = item.get("value");
            
            legendData.add(name);
            
            Map<String, Object> seriesItem = new HashMap<>();
            seriesItem.put("name", name);
            seriesItem.put("value", value);
            seriesData.add(seriesItem);
        }
        
        result.put("title", "商品库存分布");
        result.put("legendData", legendData);
        result.put("seriesData", seriesData);
        
        return result;
    }

    /**
     * 获取库存变动类型分布
     */
    @Override
    public Map<String, Object> getInventoryTypeDistribution(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取各类型变动数量分布
        List<Map<String, Object>> typeDistData = stockRecordMapper.selectTypeDistribution(startDate, endDate);
        
        // 准备饼图数据
        List<String> legendData = new ArrayList<>();
        List<Map<String, Object>> seriesData = new ArrayList<>();
        
        for (Map<String, Object> item : typeDistData) {
            String name = (String) item.get("name");
            Object value = item.get("value");
            
            legendData.add(name);
            
            Map<String, Object> seriesItem = new HashMap<>();
            seriesItem.put("name", name);
            seriesItem.put("value", value);
            seriesData.add(seriesItem);
        }
        
        result.put("title", "库存变动类型分布");
        result.put("legendData", legendData);
        result.put("seriesData", seriesData);
        
        return result;
    }

    /**
     * 获取库存变动类型趋势
     */
    @Override
    public Map<String, Object> getInventoryTypeTrend(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        
        // 获取日期标签
        List<String> dateLabels = stockRecordMapper.selectDateRange(startDate, endDate);
        result.put("labels", dateLabels);

        // 获取各类型变动趋势数据
        List<Map<String, Object>> trendData = stockRecordMapper.selectTypeTrend(startDate, endDate);
        
        // 按类型分组数据
        Map<String, List<Map<String, Object>>> typeGroups = new HashMap<>();
        for (Map<String, Object> item : trendData) {
            String type = (String) item.get("type");
            String date = (String) item.get("date");
            Object value = item.get("value");
            
            if (!typeGroups.containsKey(type)) {
                typeGroups.put(type, new ArrayList<>());
            }
            
            Map<String, Object> dataPoint = new HashMap<>();
            dataPoint.put("date", date);
            dataPoint.put("value", value);
            typeGroups.get(type).add(dataPoint);
        }
        
        // 构建数据集
        List<Map<String, Object>> datasets = new ArrayList<>();
        String[] colors = {"#409EFF", "#67C23A", "#E6A23C", "#F56C6C", "#909399", "#6B6DD6"};
        int colorIndex = 0;
        
        for (Map.Entry<String, List<Map<String, Object>>> entry : typeGroups.entrySet()) {
            String type = entry.getKey();
            List<Map<String, Object>> typeData = entry.getValue();
            
            // 按日期映射值
            Map<String, Object> dateValueMap = convertListToMap(typeData);
            
            // 构建数据集
            Map<String, Object> dataset = new HashMap<>();
            dataset.put("label", type);
            dataset.put("backgroundColor", colors[colorIndex % colors.length]);
            dataset.put("fill", false);
            
            // 为每个日期创建数据点
            List<Object> dataValues = new ArrayList<>();
            for (String date : dateLabels) {
                dataValues.add(dateValueMap.getOrDefault(date, 0));
            }
            
            dataset.put("data", dataValues);
            datasets.add(dataset);
            
            colorIndex++;
        }
        
        result.put("title", "库存变动类型趋势");
        result.put("datasets", datasets);
        
        return result;
    }

    /**
     * 更新预警阈值
     */
    @Override
    public boolean updateWarningThreshold(Integer threshold) {
        if (threshold != null && threshold > 0) {
            // TODO: 使用系统配置表或其他方式保存阈值
            return true;
        }
        return false;
    }

    /**
     * 导出库存分析报表
     */
    @Override
    public Map<String, Object> exportAnalysisReport(String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        // 获取报表数据
        result.put("overview", getInventoryOverview());
        result.put("trend", getInventoryTrend(startDate, endDate));
        result.put("comparison", getInventoryComparison(startDate, endDate));
        result.put("category", getInventoryCategory());
        return result;
    }
    
    /**
     * 将日期-值列表转换为Map形式
     * @param dataList 数据列表，每个元素包含date和value属性
     * @return 以日期为键，值为值的Map
     */
    private Map<String, Object> convertListToMap(List<Map<String, Object>> dataList) {
        Map<String, Object> result = new HashMap<>();
        for (Map<String, Object> data : dataList) {
            String date = (String) data.get("date");
            Object value = data.get("value");
            result.put(date, value);
        }
        return result;
    }
}